<script>
import paper from "paper";
import tool from "@/mixins/toolBar/tool";
import axios from "axios";
import { mapMutations, mapGetters, mapState } from "vuex";
import { BBox } from "@/libs/bbox";

export default {
  name: "AutoAnnotationTool",
  mixins: [tool],
  template:
    "<div><i v-tooltip.right='tooltip' class='fa fa-x' :class='icon' :style='{ color: iconColor }' @click='click' @mouseover='handleMouseover'></i><br></div>",
  props: {
    height: {
      type: Number,
      required: true,
    },
    width: {
      type: Number,
      required: true,
    },
    image: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      icon: "fa-crosshairs",
      name: "自动标注",
      cursor: "crosshair",
      centerPoint: null,
      points: [],
      bbox: null,
      polygon: {
        path: null,
        guidance: true,
        pathOptions: {
          strokeColor: "black",
          strokeWidth: 0.7,
        },
      },
    };
  },
  methods: {
    onMouseDown(event) {
      // console.log(this.$parent.currentCategory.category.annotations);
      // 标注点模式
      if (this.autoAnnotationPrompt == 0) {
        this.sendPoint(event.point);
        let point = this.createPoint(event.point);

        this.centerPoint = new paper.Path.Circle(point, 2);
        this.centerPoint.fillColor = this.$parent.currentAnnotation.color;
        this.centerPoint.data.point = point;

        // this.merge()
      }
      // 标注框模式
      else if (this.autoAnnotationPrompt == 1) {
        if (this.polygon.path == null) {
          this.createBBox(event);
          return;
        }
        this.removeLastBBox();
        this.modifyBBox(event);

        if (this.completeBBox()) return;
      }
    },
    onMouseMove(event) {
      if (this.autoAnnotationPrompt == 1) {
        if (this.polygon.path == null) return;
        if (this.polygon.path.segments.length === 0) return;
        this.autoStrokeColor(event.point);

        this.removeLastBBox();
        this.modifyBBox(event);
      }
    },
    autoStrokeColor(point) {
      if (this.color.circle == null) return;
      if (this.polygon.path == null) return;
      if (!this.color.auto) return;

      this.color.circle.position = point;
      let raster = this.$parent.image.raster;
      let color = raster.getAverageColor(this.color.circle);
      if (color) {
        this.polygon.pathOptions.strokeColor = invertColor(
          color.toCSS(true),
          this.color.blackOrWhite
        );
      }
    },
    createBBox(event) {
      // path路径 可以通过不同的方法将路径变为不同的形状和样式
      this.polygon.path = new paper.Path(this.polygon.pathOptions);
      this.bbox = new BBox(event.point);
      this.bbox.getPoints().forEach((point) => this.polygon.path.add(point));
    },
    modifyBBox(event) {
      this.polygon.path = new paper.Path(this.polygon.pathOptions);
      // 将矩形右下角点的坐标传入modifyPoint以修改矩形形状
      this.bbox.modifyPoint(event.point);
      this.bbox.getPoints().forEach((point) => this.polygon.path.add(point));
    },
    completeBBox() {
      // 完成一个矩形框的标注
      if (this.polygon.path == null) return false;

      this.polygon.path.fillColor = "black";

      // 关闭当前多边形路径
      this.polygon.path.closePath();
      let array = this.polygon.path._segments.map((seg) => [
        seg._point._x,
        seg._point._y,
      ]);
      let x, y;
      if (array[0][0] <= array[2][0]) x = array[0][0];
      else x = array[2][0];
      if (array[0][1] <= array[2][1]) y = array[0][1];
      else y = array[2][1];

      this.sendPoints(
        Math.round(x + this.width / 2),
        Math.round(y + this.height / 2),
        Math.round(array[2][0] - array[0][0]),
        Math.round(array[2][1] - array[0][1])
      );

      // 移除一个矩形
      this.polygon.path.remove();
      this.polygon.path = null;

      // 这个circle不知道是做什么的
      // if (this.color.circle) {
      //   this.color.circle.remove();
      //   this.color.circle = null;
      // }

      return true;
    },
    removeLastBBox() {
      this.polygon.path.removeSegments();
    },
    createPoint(point) {
      let paperPoint = new paper.Point(point.x, point.y);
      this.points.push(paperPoint);
      return paperPoint;
    },
    merge() {
      this.$parent.uniteCurrentAnnotation(this.centerPoint);

      if (this.centerPoint != null) {
        this.centerPoint.remove();
        this.centerPoint = null;
      }
    },
    sendPoint(point) {
      axios
        .post(`/api/annotation/auto`, {
          image_id: this.image.id,
          category_id: this.$parent.currentCategory.category.id,
          x: point.x + this.width / 2,
          y: point.y + this.height / 2,
        })
        .then((response) => {
          this.$parent.currentCategory.category.annotations = this.$parent.currentCategory.category.annotations.concat(
            response.data.annotations
          );
        });
    },
    sendPoints(x, y, width, height) {
      axios
        .post(`/api/annotation/auto/roi`, {
          image_id: this.image.id,
          category_id: this.$parent.currentCategory.category.id,
          x,
          y,
          width: Math.abs(width),
          height: Math.abs(height),
        })
        .then((response) => {
          this.$parent.currentCategory.category.annotations = this.$parent.currentCategory.category.annotations.concat(
            response.data.annotations
          );
        });
    },
    handleMouseover() {
      if(this.isActive) {
        this.$parent.showAutoAnnotationOption = true
      }
      else {
        this.$parent.showAutoAnnotationOption = false
      }
    },
    click() {
      this.update()
      this.$parent.showEnhancementOption = false
      if(!this.isDisabled) {
        this.$parent.showAutoAnnotationOption = true
      }
    }
  },
  computed: {
    ...mapState(["autoAnnotationPrompt"]),
    isDisabled() {
      return false;
    },
  },
  watch: {
    autoAnnotationPrompt(newValue, oldValue) {
      if (newValue == 0) {
        this.cursor = "crosshair";
      } else if (newValue == 1) {
        this.cursor = "copy";
      }
    },
  },
};
</script>
